﻿#ifndef TABLEMODEL_H
#define TABLEMODEL_H

#include "imodel.h"
#include <QAbstractTableModel>
#include <QSharedPointer>
/**
 * @class CTableModel
 * @brief 一个继承自QAbstractTableModel的类，用于管理和展示数据模型。
 */
class CTableModel:public QAbstractTableModel
{
    Q_OBJECT
public:
    /**
     * @brief 构造函数
     * @param parent 父对象，默认为nullptr
     */
    CTableModel(QObject *parent = nullptr);

public:
    /**
     * @brief 追加数据到模型中
     * @param data 需要追加的数据，类型为QSharedPointer<IModel>
     */
    void appendData(QSharedPointer<IModel> data);

    /**
     * @brief 移除指定索引的数据
     * @param index 需要移除数据的索引
     */
    void removeData(int index);

    /**
     * @brief 移除所有数据
     */
    void removeAllData();

    /**
     * @brief 删除给定数据列表中的数据项。
     * 这个函数接受一个包含QSharedPointer指向IModel接口对象的QList作为参数，会从数据列表中移除指定的数据项。
     * @param dataList 包含要移除的数据项的QList。数据项是通过QSharedPointer指针引用的IModel接口实现。
     */
    void removeData(const QList<QSharedPointer<IModel>>& dataList);

    /**
     * @brief 删除指定的数据项。
     * 这个函数接受一个指向IModel接口实现的QSharedPointer作为参数，会直接删除指定的数据项。
     * @param data 指向要删除的数据项的QSharedPointer指针。
     */
    void removeData(const QSharedPointer<IModel>& data);

    /**
     * @brief 获得行数
     */
    int rowCount();

    /**
     * @brief 根据索引获取数据模型的智能指针
     * 
     * @param index 需要获取数据的索引
     * @return QSharedPointer<IModel> 返回数据模型的智能指针。如果索引无效，可能返回空指针。
     */
    QSharedPointer<IModel> getDataByIndex(int index);

signals:
    /**
     * @brief 数据添加信号
     * @param data 添加的数据，类型为QSharedPointer<IModel>
     */
    void sigAddData(const QSharedPointer<IModel>&);

    /**
     * @brief 数据移除信号
     * @param data 被移除的数据，类型为QSharedPointer<IModel>
     */
    void sigRemoveData(const QSharedPointer<IModel>&);

    /**
     * @brief 数据更新信号
     * 该信号用于通知数据已经被更新。它可以被连接到任何对数据更新感兴趣的接收器上。
     * @param data 更新后的数据。这是一个智能指针，指向实现了IModel接口的对象。
     *             通过这个参数，接收信号的函数可以获取到最新的数据。
     * @param ret 一个引用参数，用于返回操作的状态或结果。如果更新成功，应设置为true；否则为false。
     *            这允许信号的接收者根据操作的成功与否采取不同的行动。
     */
    void sigUpdateData(const QSharedPointer<IModel>& data, bool& ret);

    // QAbstractItemModel interface
public:
    /**
     * @brief 获取行数
     * @param parent 父索引
     * @return 行数
     */
    int rowCount(const QModelIndex &parent) const;

    /**
     * @brief 获取列数
     * @param parent 父索引
     * @return 列数
     */
    int columnCount(const QModelIndex &parent) const;

    /**
     * @brief 获取指定索引处的数据
     * @param index 指定的数据索引
     * @param role 角色（表示数据的用途）
     * @return 数据的QVariant类型
     */
    QVariant data(const QModelIndex &index, int role) const;

    /**
     * 尝试设置给定模型索引处的数据。
     * 
     * @param index 指向要设置数据的模型项的索引。
     * @param value 要设置的新数据。
     * @param role 指定数据的角色（用途）。
     * @return 如果成功设置数据则返回true，否则返回false。
     */
    bool setData(const QModelIndex &index, const QVariant &value, int role);

    /**
     * @brief 获取头部数据（列头或行头）
     * @param section 头部的索引（列或行）
     * @param orientation 数据的布局方向（水平或垂直）
     * @param role 角色（表示数据的用途）
     * @return 头部数据的QVariant类型
     */
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;

    /**
     * @brief 获取指定索引处的Item的标志
     * @param index 指定的数据索引
     * @return Item的标志（如可编辑、可选择等）
     */
    Qt::ItemFlags flags(const QModelIndex &index) const;

private:
    /**
     * @brief 检查指定索引处是否有值描述
     * @param index 指定的数据索引
     * @param valuesDesMap 值描述的映射
     * @return 如果有值描述则返回true，否则返回false
     */
    bool hasValusDes(const QModelIndex &index,QMap<int,QString>& valuesDesMap) const;

private:
    QList<QSharedPointer<IModel>> m_dataList; ///< 存储数据的列表
};
#endif // TABLEMODEL_H
